<?php

namespace app\api\controller;

use app\admin\model\member\Payorder;
use app\api\model\BaseModel;
use app\api\model\ConfigModel;
use app\api\model\RecycleOrderItemModel;
use app\api\model\RecycleOrderModel;
use app\api\model\UserModel;
use app\api\model\UserWxLogModel;
use app\common\controller\Api;
use think\Db;
use think\response\Json;
use WeChatPay\Builder;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
use WeChatPay\Formatter;

use think\Log;


class Wxpaynew extends Api
{
    protected $noNeedLogin = ['notify', 'getFilePath','getPayUrl'];
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();
    }

    /**
     * 微信支付回调
     */
    public function notify()
    {
        $file = 'wx_notify';
        $testxml = file_get_contents("php://input");
        BaseModel::log($file, $testxml);
        // 记录信息日志
        Log::record('11111', 'info');
        if(!$testxml){
            echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>';
            exit('error');
        }
        $mchkey = 'Keguanawesomekeguanawesomekeguan'; //API密钥
        //转数组
        $arr_post = json_decode($testxml,true);
        //解密
        $ciphertext=(new AesUtil($mchkey))->decryptToString($arr_post['resource']['associated_data'],$arr_post['resource']['nonce'],$arr_post['resource']['ciphertext']); 
        //转数组
        $arr_ciphertext = json_decode($ciphertext,true);

        if(!empty($arr_ciphertext['out_trade_no']) and isset($arr_ciphertext['trade_state']) and $arr_ciphertext['trade_state']=='SUCCESS')
        {
             //获取订单
             $order = Payorder::where('no', $arr_ciphertext['out_trade_no'])->where('status', 0)->find();
             //修改订单
             if ($order && !$order->payment_no) {
                 //变更订单状态
                 Db::startTrans();
                 try {
                     $order->status = 1;
                     $order->pay_time = time();
                     $order->payment_no = $arr_ciphertext['transaction_id'];
                     if (!$order->save()) {
                         throw new \Exception("保存订单状态失败");
                     }
                     //修改用户
                     $result = UserModel::where('id', $order->user_id)->setInc('ocrnum', $order->num);
                     if (!$result) {
                         throw new \Exception("修改用户记录失败");
                     }
                     Db::commit();
                     echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
                     exit('succeed');
                 } catch (\Exception $e) {
                     Db::rollback();
                     BaseModel::log($file, $e->getMessage());
                     print_r( $e->getMessage());exit();
                     echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>';
                     exit('error');
                 }
            }

        }
        echo '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[ERROR]]></return_msg></xml>';
        exit('error');
        
    }
    //支付
    public function getPayUrl($order)
    {
        $appid = 'wx140c5f2e8e13d45c';
        $user = UserModel::where('id', $order['user_id'])->find();
        $r = request();
        $domain = $r->scheme() . '://' . $r->server()['SERVER_NAME'];
        // 设置参数
        // 商户号
        $merchantId = config('wx.mch_id');
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyFilePath = 'file:////www/wwwroot/zxin/public/apiclient_key.pem';
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        // 「商户API证书」的「证书序列号」
        $merchantCertificateSerial = '7E01CAA2FC7F3D78A77A437CC995FF3594326092';
        // 从本地文件中加载「微信支付平台证书」(可使用证书下载工具得到），用来验证微信支付应答的签名
        $platformCertificateFilePath = 'file:///www/wwwroot/zxin//wechatpay_34A8C9536BF702DCC9C58534FCCCF484E9D37EAF.pem';
        $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
        // 从「微信支付平台证书」中获取「证书序列号」
        $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
        // 构造一个 APIv3 客户端实例
        $instance = Builder::factory([
            'mchid'      => $merchantId,
            'serial'     => $merchantCertificateSerial,
            'privateKey' => $merchantPrivateKeyInstance,
            'certs'      => [
                $platformCertificateSerial => $platformPublicKeyInstance,
            ],
        ]);

        $js =[
            'mchid'        => $merchantId,
            'out_trade_no' =>  $order['no'],
            'appid'        => $appid,
            'description'  => '支付扫描次数',
            'notify_url'   =>'https://keguan.cc/api/Wxpaynew/notify',
            'amount'       => [
                'total'    => floatval($order['price']) * 100,
                'currency' => 'CNY'
            ],
            'payer'       => [
                'openid' => $user['openid']
            ],
        ];
        try {
            $resp = $instance
            ->chain('v3/pay/transactions/jsapi')
            ->post(['json' => $js]);
            if($resp->getStatusCode()=='200'){
                return  json_decode($resp->getBody(),true);
            }
        } catch (\Exception $e) {
        //    // 进行错误处理
            // echo $e->getMessage();
            if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
                $r = $e->getResponse();
                // echo $r->getStatusCode() . ' ' . $r->getReasonPhrase();
                return   $r->getBody();
            }
            // echo $e->getTraceAsString(), PHP_EOL;
        }
    }
    public function getFilePath($order)
    {
        // 设置参数
            // 商户号
            $merchantId = '1666779042';
            // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
            $merchantPrivateKeyFilePath = 'file:///path/to/merchant/apiclient_key.pem';
            $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
            // 「商户API证书」的「证书序列号」
            $merchantCertificateSerial = 'Keguanawesomekeguanawesomekeguan';
            // 从本地文件中加载「微信支付平台证书」(可使用证书下载工具得到），用来验证微信支付应答的签名
            $platformCertificateFilePath = 'file:///path/to/wechatpay/cert.pem';
            $platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
            // 从「微信支付平台证书」中获取「证书序列号」
            $platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
            // 构造一个 APIv3 客户端实例
            $instance = Builder::factory([
                'mchid'      => $merchantId,
                'serial'     => $merchantCertificateSerial,
                'privateKey' => $merchantPrivateKeyInstance,
                'certs'      => [
                    $platformCertificateSerial => $platformPublicKeyInstance,
                ],
            ]);
            // 以 Native 支付为例，发送请求
            $resp = $instance
            ->chain('v3/pay/transactions/native')
            ->post(['json' => [
                'mchid'        => '1900006XXX',
                'out_trade_no' => 'native12177525012014070332333',
                'appid'        => 'wxdace645e0bc2cXXX',
                'description'  => 'Image形象店-深圳腾大-QQ公仔',
                'notify_url'   => 'https://weixin.qq.com/',
                'amount'       => [
                    'total'    => 1,
                    'currency' => 'CNY'
                ],
            ]]);
            echo $resp->getBody(), PHP_EOL;
    }


    public function getPaysign($prepayID){
        $merchantPrivateKeyFilePath = 'file:////www/wwwroot/zxin/public/apiclient_key.pem';
        // 从本地文件中加载「商户API私钥」，「商户API私钥」会用来生成请求的签名
        $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
        $params =[
            'appId'=>"wx140c5f2e8e13d45c",
            'timeStamp'=>(string)Formatter::timestamp(),
            'nonceStr'=>Formatter::nonce(),
            'package'=>"prepay_id=$prepayID",
            // 'package'=>'prepay_id='+$prepayID
        ];
        $params +=[
            'paySign'=> Rsa::sign(Formatter::joinedByLineFeed(...array_values($params)),$merchantPrivateKeyInstance),
            'signType'=> 'RSA'
           ];
        return $params;
    }
}